﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;

//[ExecuteInEditMode]
public class RTShadow : MonoBehaviour
{
    public RenderTexture mRenderTexture;
    public Camera mCam;
    public Shader mSimpleMultiShader;
    private Material mBlitMat;
    private bool useDXR = false;
    // Start is called before the first frame update
    void Start()
    {
        mBlitMat = new Material(mSimpleMultiShader);
    }

    private void OnGUI()
    {
        if(GUILayout.Button("Start"))
        {
            RTScene.Instance.InitSystem();
            var resolution = new Vector2Int(mCam.pixelWidth, mCam.pixelHeight);
            mRenderTexture = new RenderTexture(resolution.x, resolution.y, 0, RenderTextureFormat.RHalf);
            mRenderTexture.name = "RaytracedHardShadow";
            mRenderTexture.enableRandomWrite = true; // enable unordered access
            mRenderTexture.Create();

            RTScene.Instance.SetRenderTarget(mRenderTexture, Screen.width, Screen.height, RTScene.dxrRenderTargetFormat.Ru8);
            GoThroughEntireScene();

            RTScene.Instance.SetCamera(mCam);

            useDXR = true;

            mBlitMat.SetTexture("_ShadowTex", mRenderTexture);
        }
    }

    // Update is called once per frame
    void Update()
    {
        foreach (var l in FindObjectsOfType<Light>())
        {
            //简单的暂时只处理方向光
            if (l.type == LightType.Directional)
                RTScene.Instance.UpdateLight(l);
        }

        foreach (var mr in FindObjectsOfType<MeshRenderer>())
        {
            RTScene.Instance.UpdateMeshRender(mr);
        }
    }

    void OnPreRender()
    {
        if (useDXR)
            RTScene.Instance.RenderFrame();
    }

    void GoThroughEntireScene()
    {
        foreach (var l in FindObjectsOfType<Light>())
        {
            //简单的暂时只处理方向光
            if (l.type == LightType.Directional)
                RTScene.Instance.AddLight(l);
        }

        foreach (var mr in FindObjectsOfType<MeshRenderer>())
        {
            RTScene.Instance.AddMeshRender(mr);
        }
    }

    private void OnDestroy()
    {
        if (useDXR)
        {
            useDXR = false;
            RTScene.Instance.SetCamera(null);
            RTScene.Instance.ClearSceneData();
            RTScene.Instance.SetRenderTarget(null, 0, 0, 0);
            if (mRenderTexture)
            {
                mRenderTexture.DiscardContents();
                mRenderTexture.Release();
            }
            RTScene.Instance.UnInitSystem();
        }
    }

    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (useDXR)
            Graphics.Blit(src, dest, mBlitMat, 0);
        else
            Graphics.Blit(src, dest);
    }
}
